<!--
 * @Author: maomao
 * @Date: 2021-04-30 10:46:20
 * @Description: 
 * @FilePath: \dictionary-web\src\components\tree-left.vue
-->
<template>
  <div class="tree-area">
    <dx-treeView
      id="treeview"
      ref="treeViewRef"
      v-bind="treeSetting"
      v-model:create-children="createChildren"
      @item-click="handleItemClick"
      @item-expanded="onItemExpanded"
      @item-context-menu="treeViewItemContextMenu"
    />
    <dx-contextMenu
      ref="contextMenuRef"
      v-bind="contextSetting"
      @item-click="contextMenuItemClick"
    />
    <div class="menu-popup">
      <dx-popup
        v-bind="popupSetting"
        :title="isEdit ? '修改目录' : '新建目录'"
        v-model:visible="popupVisible"
      >
        <dx-form v-bind="formSetting" ref="formRef"></dx-form>
        <div class="button-bar">
          <dx-button
            text="取消"
            :width="100"
            @click="popupVisible = false"
          ></dx-button>
          <dx-button text="确认" :width="100" @click="onSubmit"></dx-button>
        </div>
      </dx-popup>
    </div>
  </div>
</template>
<script lang='ts'>
import { ApiTool } from "@/api/api-tool";
import { CatalogClient } from "@/api/api_catalogclient";
import {
  CatalogOutput,
  GetPagedCatalogInput,
  InsertOrUpdateCatelogInput,
} from "@/api/api_solutionclient";
import { PageInfo } from "@/utils/page_utils";
import { SearchByURL } from "@/utils/search-byurl";
import DxTreeView from "devextreme-vue/tree-view";
import DxContextMenu from "devextreme-vue/context-menu";
import { DxPopup } from "devextreme-vue/popup";
import { DxForm } from "devextreme-vue/form";
import { DxButton } from "devextreme-vue/button";
import { dxTreeViewOptions } from "devextreme/ui/tree_view";
import {
  Inject,
  Options,
  Prop,
  Ref,
  Vue,
  Watch,
} from "vue-property-decorator/lib";
import { dxContextMenuOptions } from "devextreme/ui/context_menu";
import { dxPopupOptions } from "devextreme/ui/popup";
import { dxFormOptions } from "devextreme/ui/form";
import { dxValidationGroupResult } from "devextreme/ui/validation_group";
import { ViewTool } from "@/utils/view-tool";
import notify from "devextreme/ui/notify";
import { DialogUtil } from "@/utils/dialog-util";
import { Tool } from "@/utils/tool";
/**目录结构 */
interface CatalogEntity {
  /** 等级 */
  grade?: number;
  /** 名称 */
  name?: string | undefined;
  /** 租户Id */
  eid?: string | undefined;
  /** 业务标识 */
  logicIdentity?: string | undefined;
  /** 父级Id */
  parentId?: string | undefined;
  /** Id */
  displayId?: string | undefined;
  /** Id */
  catalogId?: string;
  /** 方案Id */
  solutionId?: string;
  /** 是否展开 */
  expanded?: boolean | undefined;
  hasChildren?: Boolean | undefined;
  selected?: boolean;
}

@Options({
  components: {
    DxContextMenu,
    DxTreeView,
    DxButton,
    DxPopup,
    DxForm,
  },
})
export default class TreeLeft extends Vue {
  @Prop()
  item: CatalogOutput;

  @Ref()
  treeViewRef: DxTreeView;

  @Ref()
  contextMenuRef: DxContextMenu;

  @Ref()
  formRef: DxForm;

  @Inject()
  apiTool: ApiTool;

  menuItems = [
    {
      id: 1,
      text: "新建",
      items: [
        {
          id: 101,
          text: "同级目录",
        },
        {
          id: 102,
          text: "子集目录",
        },
      ],
    },
    { id: 2, text: "修改" },
    { id: 3, text: "删除" },
  ];

  selectedTreeItem: CatalogOutput = undefined;
  selectedTreeIds: string[] = [];
  isEdit = false;
  popupVisible = false;

  addFormData: InsertOrUpdateCatelogInput = {
    grade: 1,
    name: "",
    parentId: "",
    catalogId: "",
    displayId: "",
    solutionId: "",
  };

  searchByUrl: SearchByURL = null;
  catalogList: CatalogEntity[] = [];

  treeSetting: dxTreeViewOptions = {
    dataStructure: "plain",
    height: "100%",
    width: 300,
    rootValue: "",
    displayExpr: "name",
    keyExpr: "catalogId",
    selectionMode: "single",
    expandEvent: "dblclick",
    noDataText: "暂无分类目录",
    hasItemsExpr: "hasChildren",
    elementAttr: {
      class: "navigation-list",
    },
  };

  contextSetting: dxContextMenuOptions = {
    items: this.menuItems,
    target: "#treeview .dx-item",
  };

  popupSetting: dxPopupOptions = {
    closeOnOutsideClick: true,
    width: 500,
    height: 500,
    elementAttr: {
      class: "navigation-popup",
    },
  };

  formSetting: dxFormOptions = {
    formData: this.addFormData,
    colCount: 1,
    showColonAfterLabel: true,
    showValidationSummary: true,
    validationGroup: "customerData",
    labelLocation: "left",
    readOnly: false,

    items: [
      {
        label: {
          text: "ID",
        },
        dataField: "displayId",
        isRequired: true,
        editorOptions: {
          stylingMode: "outlined",
        },
        validationRules: [
          {
            message: "id不能为中文字符",
            pattern: /^\w+$/,
            type: "pattern",
          },
        ],
      },
      {
        label: {
          text: "目录名称",
        },
        dataField: "name",
        isRequired: true,
        editorOptions: {
          stylingMode: "outlined",
        },
      },
    ],
  };

  @Watch("item", {
    deep: true,
    immediate: true,
  })
  watchItem(value) {
    if (value.grade === 1) {
      this.formData.parentId = value.catalogId;
      this.formData.solutionId = value.solutionId;
      this.formData.grade = 1;

      ///获取 选择层级id
      let treeIds = this.$route.query.treeIds as string;
      if (treeIds && treeIds.indexOf("-") != -1) {
        this.selectedTreeIds = treeIds.split("-");
      } else {
        this.selectedTreeIds.push(treeIds ?? "");
      }
    }
  }

  page: PageInfo = {
    index: 0,
    count: 0,
    pageSize: 100,
    pageCount: 0,
  };

  formData: GetPagedCatalogInput = {
    page: this.page,
    solutionId: "",
    parentId: "",
    grade: 1,
  };

  async createChildren(parent) {
    this.formData.parentId = parent
      ? parent.itemData.id
      : this.formData.parentId;
    this.formData.grade = parent ? parent.itemData.grade + 1 : 1;
    let client = this.apiTool.createClient(CatalogClient);
    let result = await client.getListCatalog(this.formData);

    ///获取数据
    let items = result.listData.map((_val, key) => {
      let item: CatalogEntity = {
        hasChildren: _val.hasChildren,
        parentId: this.formData.grade == 1 ? "" : this.formData.parentId,
        name: _val.name,
        grade: _val.grade,
        solutionId: _val.solutionId,
        catalogId: _val.catalogId,
        displayId: _val.displayId,
        expanded: this.setExpanded(_val, key),
        selected: this.setSelection(_val, key),
      };
      return item;
    });
    this.catalogList.concat(items);
    return items;
  }

  /** 点击以后的设置 */
  handleItemClick(e: { itemData: CatalogEntity; event }) {
    if (!e.itemData.catalogId) return;
    //判断坐标位置
    if (this.selectedTreeIds.length > e.itemData.grade) {
      this.selectedTreeIds[e.itemData.grade] = e.itemData.catalogId;
      this.selectedTreeIds = this.selectedTreeIds.filter((_val, key) => {
        return e.itemData.grade >= key;
      });
    } else {
      this.selectedTreeIds.push(e.itemData.catalogId);
    }
    this.updateSelection(e.itemData);
    this.formData.grade = -1;
    this.onSetParamsToUrl(e.itemData);
    const pointerEvent = e.event;
    pointerEvent.stopPropagation();
  }

  /** 展开以后的设置 */
  onItemExpanded(e) {
    if (!e.itemData.id) return;
    //判断坐标位置
    if (this.selectedTreeIds.length > e.itemData.grade) {
      this.selectedTreeIds[e.itemData.grade] = e.itemData.id;
      this.selectedTreeIds = this.selectedTreeIds.filter((_val, key) => {
        return e.itemData.grade >= key;
      });
    } else {
      this.selectedTreeIds.push(e.itemData.id);
    }
    this.updateSelection(e.itemData);
    this.formData.grade = -1;
    this.onSetParamsToUrl(e.itemData);
  }

  /** 设置是否能够点击 */
  treeViewItemContextMenu(e) {
    this.selectedTreeItem = e.itemData;
    if (this.selectedTreeItem.grade === 3) {
      this.contextMenuRef.instance.option("items[0].items[1].disabled", true);
    }
    let delDisabled = this.selectedTreeItem.hasChildren;
    this.contextMenuRef.instance.option("items[2].disabled", delDisabled);
    ///右键时 也默认选中状态
    this.onItemExpanded(e);
  }

  ///更新选中状态
  updateSelection(_item: CatalogEntity) {
    this.treeViewRef.instance.selectItem(_item);
  }

  /* 更新展开状态 */
  setExpanded(_item: CatalogEntity, key: number) {
    let treeId = "";
    let isExpand = false;
    if (this.selectedTreeIds.length > _item.grade) {
      treeId = this.selectedTreeIds[_item.grade];
    }

    isExpand = Tool.isEmpty(treeId) ? key == 0 : treeId === _item.catalogId;
    if (_item.grade === 1 && this.selectedTreeIds.length === 1 && key === 0) {
      this.selectedTreeIds.push(_item.catalogId);
    }
    return isExpand;
  }

  /* 更新选择状态 */
  setSelection(_item: CatalogEntity, Key: number) {
    let selectId = "";
    selectId = this.selectedTreeIds[this.selectedTreeIds.length - 1];
    if (selectId === _item.catalogId) {
      this.onSetParamsToUrl(_item);
      return true;
    }
    return false;
  }

  contextMenuItemClick(e) {
    let key = e.itemData.id;
    this.addFormData.solutionId = this.selectedTreeItem.solutionId;

    switch (key) {
      case 101:
        this.isEdit = false;
        this.popupVisible = true;
        this.addFormData.catalogId = "";
        this.addFormData.name = "";
        this.addFormData.displayId = "";
        this.addFormData.parentId = this.selectedTreeItem.parentId;
        this.addFormData.grade = this.selectedTreeItem.grade;
        this.addFormData.displayId = this.selectedTreeItem.displayId;
        break;
      case 102:
        this.isEdit = false;
        this.popupVisible = true;
        this.addFormData.name = "";
        this.addFormData.displayId = this.selectedTreeItem.displayId;
        this.addFormData.catalogId = this.selectedTreeItem.catalogId;
        this.addFormData.parentId = this.selectedTreeItem.catalogId;
        this.addFormData.grade = this.selectedTreeItem.grade + 1;
        break;
      case 2:
        this.isEdit = true;
        this.popupVisible = true;
        this.addFormData.catalogId = this.selectedTreeItem.catalogId;
        this.addFormData.name = this.selectedTreeItem.name;
        this.addFormData.grade = this.selectedTreeItem.grade;
        this.addFormData.parentId = this.selectedTreeItem.parentId;
        break;
      case 3:
        this.onDelCatalog();
        break;
      default:
        break;
    }
  }

  onSetParamsToUrl(item) {
    let form = {
      solutionId: item.solutionId,
      catalogId: item.id,
      treeIds: this.selectedTreeIds.join("-"),
    };
    this.searchByUrl.setParamsToUrl(form);
  }

  onSubmit(e) {
    let validate: dxValidationGroupResult = this.formRef.instance.validate();
    if (validate.isValid) {
      ViewTool.showLoading(true, this);
      if (this.isEdit) {
        this.onEditCatalog(this.addFormData);
      } else {
        this.onAddCatalog(this.addFormData);
      }
    }
  }

  onAddCatalog(_formData: InsertOrUpdateCatelogInput) {
    let client = this.apiTool.createClient(CatalogClient);
    client
      .insertOrUpdateCatalog(_formData)
      .then((model) => {
        if (model.isSuccess) {
          notify("添加成功", "success");
          this.popupVisible = false;
          this.refresh();
        } else {
          notify(model.message, "error");
        }
      })
      .catch((error) => {
        notify(error, "error");
      });
    ViewTool.showLoading(false, this);
  }

  onEditCatalog(_formData: InsertOrUpdateCatelogInput) {
    let client = this.apiTool.createClient(CatalogClient);
    client
      .insertOrUpdateCatalog(_formData)
      .then((model) => {
        if (model.isSuccess) {
          notify("修改成功", "success");
          this.popupVisible = false;
          this.refresh();
        } else {
          notify(model.message, "error");
        }
      })
      .catch((error) => {
        notify(error, "error");
      });
  }

  onDelCatalog() {
    DialogUtil.confirm({
      content: `你确认要删除目录“${this.selectedTreeItem.name}”吗？`,
      confirm: "删除",
      cancel: "取消",
    }).then((res) => {
      if (res) {
        ViewTool.showLoading(true, this);
        let client = this.apiTool.createClient(CatalogClient);
        client
          .deleteCatalog({
            catalogId: this.selectedTreeItem.catalogId,
            solutionId: this.selectedTreeItem.solutionId,
          })
          .then((model) => {
            if (model.isSuccess) {
              notify("删除成功", "success");
              this.popupVisible = false;
              this.formData.grade = 1;
              this.refresh();
            } else {
              notify(model.message, "error");
            }
          })
          .catch((error) => {
            notify(error, "error");
          });
        ViewTool.showLoading(false, this);
      }
    });
  }

  refresh() {
    this.$router.replace({ path: "/refresh" });
  }

  mounted() {
    this.searchByUrl = new SearchByURL(this.$router);
  }
}
</script>
<style lang="scss" scoped src="./side-nav-menu.scss">
.tree-area {
  width: 300px;
  min-height: 100%;
  height: 100%;
  width: 300px !important;
  display: flex;
}
</style>